﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework.Content;
using System.Xml;
using System.Collections;

namespace MobMentality.Map
{
	/*
	 * Static class for loading maps from XML
	 */
	public class MapBuilder
	{
		/*
		 * filename - file to load map from (xml file)
		 * content - ContentManager allows us to load the textures for the map
		 */
		public static IMapDraw getMapDraw(string filename, ContentManager content, int screenWidth, int screenHeight)
		{
			XmlTextReader reader = new XmlTextReader(filename);
			MapDraw map = null;

			while (reader.Read())
			{
				switch (reader.Name)
				{
					case "Header":
						map = ReadDrawHeader(reader, content, screenWidth, screenHeight);
						break;
					case "Tile":
						map.AddTile(int.Parse(reader.GetAttribute("row")),
									int.Parse(reader.GetAttribute("column")), 
									reader.ReadElementContentAsString());
						break;
					default:
						//WTF?
						break;
				}
			}

			return map;
		}

		/*get header info such as rows, columns, and images in this level*/
		private static MapDraw ReadDrawHeader(XmlTextReader reader, ContentManager content, int screenWidth, int screenHeight)
		{
			int rows = 0;
			int columns = 0;
			int tileWidth = 0;
			int tileHeight = 0;
			Dictionary<string,string> filenames = new Dictionary<string,string>();

			while (reader.Read())
			{
				//if the header is over
				if (reader.NodeType == XmlNodeType.EndElement && reader.Name.Equals("Header"))
				{
					//bail
					break;
				}

				if (reader.NodeType == XmlNodeType.Element)
				{
					switch (reader.Name)
					{
						case "rows":
							rows = reader.ReadElementContentAsInt();
							break;
						case "columns":
							columns = reader.ReadElementContentAsInt();
							break;
						case "tileWidth":
							tileWidth = reader.ReadElementContentAsInt();
							break;
						case "tileHeight":
							tileHeight = reader.ReadElementContentAsInt();
							break;
						case "tileType":
							filenames.Add(reader.GetAttribute("name"), reader.ReadElementContentAsString());
							break;
						default:
							break;
					}
				}
			}

			return new MapDraw(rows, columns, tileWidth, tileHeight, filenames, content, screenWidth, screenHeight);
		}

		/*
		 * filename - file to load map from (xml file)
		 */
		public static IMapNavigate getMapNavigate(string filename)
		{
			XmlTextReader reader = new XmlTextReader(filename);
			MapNavigate map = null;

			while (reader.Read())
			{
				switch (reader.Name)
				{
					case "Header":
						map = ReadNavigateHeader(reader);
						break;
					case "Tile":
						map.AddTile(int.Parse(reader.GetAttribute("row")),
									int.Parse(reader.GetAttribute("column")),
									reader.ReadElementContentAsString());
						break;
					default:
						//WTF?
						break;
				}
			}

			/*Last thing we have to do is construct the navmesh*/
			map.ConstructNavmesh();

			return map;
		}

		/*get header info such as rows, columns, and nav types in this level*/
		private static MapNavigate ReadNavigateHeader(XmlTextReader reader)
		{
			int rows = 0;
			int columns = 0;
			int tileWidth = 0;
			int tileHeight = 0;
			Dictionary<string, string> navigationTypeMap = new Dictionary<string, string>();

			while (reader.Read())
			{
				//if the header is over
				if (reader.NodeType == XmlNodeType.EndElement && reader.Name.Equals("Header"))
				{
					//bail
					break;
				}

				if (reader.NodeType == XmlNodeType.Element)
				{
					switch (reader.Name)
					{
						case "rows":
							rows = reader.ReadElementContentAsInt();
							break;
						case "columns":
							columns = reader.ReadElementContentAsInt();
							break;
						case "tileWidth":
							tileWidth = reader.ReadElementContentAsInt();
							break;
						case "tileHeight":
							tileHeight = reader.ReadElementContentAsInt();
							break;
						case "tileType":
							navigationTypeMap.Add(reader.GetAttribute("name"), reader.GetAttribute("navType"));
							break;
						default:
							break;
					}
				}
			}

			return new MapNavigate(rows, columns, tileWidth, tileHeight, navigationTypeMap);
		}
	}
}
